Skip to content

format: a setting value is spelled the way the format declares it - #39

Merged
donislawdev merged 1 commit into
mainfrom
format/one-voice-for-closed-sets
Sep 2, 2026
Merged

format: a setting value is spelled the way the format declares it#39
donislawdev merged 1 commit into
mainfrom
format/one-voice-for-closed-sets

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

Closes the two voice refusal recorded as O168 - and the measurement that
went with it found something larger, so this fixes that instead.

What was wrong

The registry compared a closed set with EqualFold and a boolean with
ToLower. A value the declaration does not contain therefore passed the
one check meant to stop it and reached the generator, and what happened
next was each generator's own decision.

Measured across all eight formats that declare a closed set, twenty one
settings, every declared value offered in a case the declaration does not
use. Zero of them were refused by the registry. Four behaviours, none
of them declared:

behaviour where
refuses in its own words csv 3/3, ico, log 6/6, wav content
folds and understands it pdf page_size, directory_entries in both archives
swallows it and builds the default file targz entry_owner
reads it as another value zip encryption=NONE

--set entry_owner=USER produced an archive owned by nobody - byte for
byte the default file - with exit 0 and nothing said. --set encryption=NONE went on to demand a password to lock an archive "with
NONE", quoting a value the format does not have.

What this does

  • Property.Allows compares exactly. One place, rather than twenty one
    settings, and no generator is ever handed a value its declaration does
    not spell.
  • ReadOwnership gains the default branch it never had. The registry
    stops a misspelling earlier now, so this is about the other door: the
    function is callable directly, and silence there is the same wrong file.
  • targz records entry_mode and entry_owner in the manifest. Neither
    reached it before - which is exactly why a swallowed owner was
    invisible: a run asking for user and a run asking for USER produced
    identical manifests.

Breaking, and named as such in the changelog

--set page_size=A4 and --set directory_entries=TRUE used to work and
now refuse with exit 4. No file changes its bytes. A recipe writing
header: true is unaffected, because a YAML boolean arrives as true
either way - only a value quoted into another case is refused.

Guards

Three, in internal/guard/closedsets_test.go, all red before the change:
63 values walked from the registry itself rather than from a list copied
beside it, plus the 14 values that carry no letters, counted and printed
so that a day when this guard walks nothing is a day it says so.

Five mutation entries, all caught. One existing entry went stale on this
change and was repaired - staleness.py is clean at 724.

Full suite green (internal/guard 297.9s), preflight green on ten gates
including staticcheck, lint and govulncheck.

🤖 Generated with Claude Code

The registry compared a closed set with EqualFold and a boolean with
ToLower, so a value the declaration does not contain walked past the one
check meant to stop it and arrived at the generator. What happened next
was each generator's own decision, and measured across the eight formats
that declare a closed set there were four of them:

  refuse in its own words   csv, ico, log, wav
  fold and understand it    pdf page_size, directory_entries in archives
  swallow it and build the  targz entry_owner - USER and ROOT produced a
    DEFAULT file, exit 0      file byte for byte identical to unset
  read it as another value  zip encryption=NONE, which then asked for a
                              password to lock an archive "with NONE"

The third is a file that is not what was ordered, reported as success.

Allows now compares exactly, which is one place rather than twenty one
settings, and no generator is handed a value its own declaration does
not spell. ReadOwnership gains the default branch it never had, because
that function is callable directly and silence there would be the same
wrong file through another door. And targz records entry_mode and
entry_owner in the manifest - neither reached it before, which is why a
swallowed owner left nothing to disagree with.

Three guards walk the whole registry rather than a list copied beside
them: 63 values in a case the declaration does not use, plus the 14 that
carry no letters, counted and printed so a day when this guard walks
nothing is a day it says so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit b759330 into main Sep 2, 2026
30 of 31 checks passed
@donislawdev
donislawdev deleted the format/one-voice-for-closed-sets branch September 2, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant